package com.wy.springbootblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wy.springbootblog.mapper.ArticleMapper;
import com.wy.springbootblog.mapper.ArticleTagMapper;
import com.wy.springbootblog.pojo.Article;
import com.wy.springbootblog.pojo.ArticleTag;
import com.wy.springbootblog.pojo.Result;
import com.wy.springbootblog.pojo.SearchBean;
import com.wy.springbootblog.service.ArticleService;
import com.wy.springbootblog.service.ArticleTagService;
import com.wy.springbootblog.util.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author work
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Autowired
    private ArticleTagService articleTagService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 新增文章
    @Override
    public Result<Void> saveArticle(Article article) {
        // 1.判断用户身份权限
        Map<String, Object> map = ThreadLocalUtil.get();
        String role = (String) map.get("role");
        if (!Objects.equals(role, "admin")) {
            // 没有新增文章权限
            return Result.error("该用户无新增文章权限");
        }
        // 2.查询浏览数views
        article.setViews(0L);
        // 3.查询评论数comment_count
        article.setCommentCount(0);
        // 4.新增文章基本内容
        article.setCreateTime(LocalDateTime.now());
        article.setUpdateTime(LocalDateTime.now());
        article.setFlag(0);
        // 5. 设置文章属于哪一个用户（article）
        Integer userId = (Integer) map.get("id");
        article.setUserId(userId);
        articleMapper.insert(article);
        // 6. 设置文章属于哪一个分类(article)
        // 7. 设置文章有那几个标签(article_tag) [1, 2, 3]
        if (article.getTagList() != null && !article.getTagList().isEmpty()) {
            List<ArticleTag> add = new ArrayList<>();
            for (int i = 0; i < article.getTagList().size(); i++) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setTagId(article.getTagList().get(i));
                articleTag.setArticleId(article.getId());
                articleTag.setCreateTime(LocalDateTime.now());
                articleTag.setUpdateTime(LocalDateTime.now());
                articleTag.setFlag(0);
                add.add(articleTag);
                //todo:赋值
            }
            articleTagService.saveBatch(add);
            return Result.success();
        } else {
            return Result.error("文章标签不能为空");
        }
    }

    // 删除文章
    @Override
    public Result<Void> deleteArticle(Integer id) {
        // 1.判断用户身份权限
        Map<String, Object> map = ThreadLocalUtil.get();
        String role = (String) map.get("role");
        if (!Objects.equals(role, "admin")) {
            // 没有新增文章权限
            return Result.error("该用户无删除文章权限");
        }
        // 2.删除文章article
        Article article = new Article();
        article.setId(id);
        article.setFlag(1);
        articleMapper.update(article, new LambdaQueryWrapper<Article>().eq(Article::getId, id));
        // 3.删除文章标签关系表article_tag（使用articleId进行查询） // 有外键约束不建议删除，可以添加标记进行假删除
        ArticleTag articleTag = new ArticleTag();
        articleTag.setArticleId(id);
        articleTag.setFlag(1);
        articleTagMapper.update(articleTag, new LambdaQueryWrapper<ArticleTag>().eq(ArticleTag::getArticleId, id));
        return Result.success();
    }

    // 分页条件查询文章列表
    @Override
    public Result<List<Article>> articleList(SearchBean<Article> searchBean) {
        // 分页查询
        Page<Article> page = new Page<Article>(searchBean.getPageNum(), searchBean.getPageSize());
        QueryWrapper<Article> queryWrapper = new QueryWrapper<Article>();
        queryWrapper.eq("flag", 0);
        // 模糊查询文章标题title
        if (searchBean.getQuery() != null && searchBean.getQuery().getTitle() != null) {
            queryWrapper.like("title", searchBean.getQuery().getTitle());
        }
        articleMapper.selectPage(page, queryWrapper);
        return Result.success(page.getRecords(), page.getTotal());
    }

    // 更新文章
    @Override
    public Result<Void> updateArticle(Article article) {
        // 1.判断用户身份权限
        Map<String, Object> map = ThreadLocalUtil.get();
        String role = (String) map.get("role");
        if (!Objects.equals(role, "admin")) {
            // 没有新增文章权限
            return Result.error("该用户无更新文章权限");
        }
        // 2.判断文章是否存在
        Article articleQuery = articleMapper.selectById(article.getId());
        if (articleQuery == null) {
            return Result.error("文章不存在");
        }
        // 3.更新文章
        // 3.1 更新基本内容和分类
        article.setUpdateTime(LocalDateTime.now());
        articleMapper.updateById(article);
        // 3.2 更新标签
        if (article.getTagList() != null && !article.getTagList().isEmpty()) {
            List<ArticleTag> add = new ArrayList<>();
            for (int i = 0; i < article.getTagList().size(); i++) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setTagId(article.getTagList().get(i));
                articleTag.setArticleId(article.getId());
                articleTag.setCreateTime(LocalDateTime.now());
                articleTag.setUpdateTime(LocalDateTime.now());
                articleTag.setFlag(0);
                add.add(articleTag);
                //todo:赋值
            }
            articleTagService.saveBatch(add);
            return Result.success();
        } else {
            return Result.error("文章标签不能为空");
        }
    }

    // 查询文章详情
    @Override
    public Result articleDetail(Integer id) {
        // 1.判断文章是否存在
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<Article>();
        queryWrapper.eq(Article::getId, id);
        queryWrapper.eq(Article::getFlag, 0);
        Article articleQuery = articleMapper.selectOne(queryWrapper);
//        Article articleQuery = articleMapper.selectById(id);
        if (articleQuery == null) {
            return Result.error("文章不存在");
        }
        // 2.从缓存中获取浏览量views
        Integer views = (Integer) redisTemplate.opsForValue().get("article:views:" + id);
        if (views != null) {
            // 缓存有数据
            // 更新数据库中得浏览量
            updateViews(id, Long.valueOf(views));
        }
        // 3.从数据库中获取博客详情
        Article article = articleMapper.selectById(id);
//        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<Article>();
//        queryWrapper.eq(Article::getId, id);
//        queryWrapper.eq(Article::getFlag, 0);
//        articleMapper.selectOne(queryWrapper);
        return Result.success(article);
    }

    // 增加博客详情浏览量
    @Override
    public void increaseViews(Integer id) {
        // 浏览量加1
        Long views = redisTemplate.opsForValue().increment("article:views:" + id);
        if (views == null) {
            // 缓存中不存在，从数据库中获取，并存入缓存
            Article article = articleMapper.selectById(id);
            if (article != null) {
                views = article.getViews();
                redisTemplate.opsForValue().set("article:views:" + id, String.valueOf(views));
            }
        }
    }

    // 更新浏览量
    private void updateViews(Integer id, Long views) {
        Article article = new Article();
        article.setId(id);
        article.setViews(views);
        articleMapper.updateById(article);
    }
}
